package com.zsc.common.utils.file;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.PutObjectRequest;
import com.zsc.common.constant.AliOssProperties;
import com.zsc.common.utils.uuid.UUID;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.time.LocalDateTime;

@Data
@Slf4j
@Component // 改为 Spring 管理的 Bean
public class AliOssUtil {

    private final String endpoint;
    private final String accessKeyId;
    private final String accessKeySecret;
    private final String bucketName;
    private final String accessPre;
    private final OSS ossClient;

    @Autowired
    public AliOssUtil(AliOssProperties aliOssProperties) {
        this.endpoint = aliOssProperties.getEndpoint();
        this.accessKeyId = aliOssProperties.getAccessKeyId();
        this.accessKeySecret = aliOssProperties.getAccessKeySecret();
        this.bucketName = aliOssProperties.getBucketName();
        this.accessPre = "https://" + bucketName + "." + endpoint + "/";
        this.ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        log.info("OSS 服务连接成功！");
    }

    /**
     * 默认路径上传本地文件
     */
    public String uploadFile(String filePath) {
        return uploadFileForBucket(bucketName, getOssFilePath(filePath), filePath);
    }

    /**
     * 默认路径上传 MultipartFile 文件
     */
    public String uploadMultipartFile(MultipartFile multipartFile) {
        return uploadMultipartFile(bucketName, getOssFilePath(multipartFile.getOriginalFilename()), multipartFile);
    }

    /**
     * 上传 MultipartFile 文件到指定 Bucket
     */
    public String uploadMultipartFile(String bucketName, String ossPath, MultipartFile multipartFile) {
        try (InputStream inputStream = multipartFile.getInputStream()) {
            uploadFileInputStreamForBucket(bucketName, ossPath, inputStream);
            return accessPre + ossPath;
        } catch (IOException e) {
            log.error("文件上传失败", e);
            throw new RuntimeException("文件上传失败", e);
        }
    }

    /**
     * 使用 File 上传文件到指定 Bucket
     */
    public String uploadFileForBucket(String bucketName, String ossPath, String filePath) {
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, ossPath, new File(filePath));
        ossClient.putObject(putObjectRequest);
        return accessPre + ossPath;
    }

    /**
     * 使用文件流上传到指定 Bucket
     */
    public String uploadFileInputStreamForBucket(String bucketName, String ossPath, String filePath) {
        try (InputStream inputStream = new FileInputStream(filePath)) {
            uploadFileInputStreamForBucket(bucketName, ossPath, inputStream);
            return accessPre + ossPath;
        } catch (FileNotFoundException e) {
            log.error("文件未找到", e);
            throw new RuntimeException("文件未找到", e);
        } catch (IOException e) {
            log.error("文件上传失败", e);
            throw new RuntimeException("文件上传失败", e);
        }
    }

    public void uploadFileInputStreamForBucket(String bucketName, String ossPath, InputStream inputStream) {
        ossClient.putObject(bucketName, ossPath, inputStream);
    }

    /**
     * 下载文件
     */
    public void downloadFile(String ossFilePath, String filePath) {
        downloadFileForBucket(bucketName, ossFilePath, filePath);
    }

    /**
     * 下载文件到指定 Bucket
     */
    public void downloadFileForBucket(String bucketName, String ossFilePath, String filePath) {
        ossClient.getObject(new GetObjectRequest(bucketName, ossFilePath), new File(filePath));
    }

    /**
     * 获取 OSS 默认路径
     */
    public String getOssDefaultPath() {
        LocalDateTime now = LocalDateTime.now();
        return now.getYear() + "/" +
                now.getMonthValue() + "/" +
                now.getDayOfMonth() + "/" +
                now.getHour() + "/" +
                now.getMinute() + "/";
    }

    /**
     * 获取 OSS 文件路径
     */
    public String getOssFilePath(String filePath) {
        String fileSuf = filePath.substring(filePath.lastIndexOf(".") + 1);
        return getOssDefaultPath() + UUID.randomUUID().toString() + "." + fileSuf;
    }
}
